import 'package:flutter/material.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:qunaimedical/components/custom_divider.dart';
import 'package:qunaimedical/components/item_record_publish.dart';
import 'package:qunaimedical/models/consultation_record.dart';
import 'package:qunaimedical/models/department.dart';
import 'package:qunaimedical/models/list_response.dart';
import 'package:qunaimedical/models/map_response.dart';
import 'package:qunaimedical/network/http.dart';
import 'package:qunaimedical/utils/toast_util.dart';
import 'package:qunaimedical/values/constants.dart';
import 'package:qunaimedical/values/urls.dart';
import 'package:sprintf/sprintf.dart';

/// 预约会诊大厅
class PublicConsultationRecordListPage extends StatefulWidget {
  static const String routeName = '/public/consultationRecordList';

  @override
  _PublicConsultationRecordListPageState createState() =>
      _PublicConsultationRecordListPageState();
}

class _PublicConsultationRecordListPageState
    extends State<PublicConsultationRecordListPage> {
  List<ConsultationRecord> _items = [];

  /// 科室列表。
  List<Department> _departments = [];

  /// 已选择的科室索引
  int _selectedDepartmentIndex;

  /// 会诊类型列表。
  List<Department> _consultationTypes = [];

  /// 已选择的类型索引
  int _selectedConsultationIndex;

  /// 选择器key
  GlobalKey selectorKey = GlobalKey();

  // 是否有下一页
  int _nextPage = 1;

  RefreshController _refreshController =
      RefreshController(initialRefresh: true);

  @override
  void initState() {
    super.initState();
    _getDepartmentTypes();
    _getConsultationTypes();
    _fetchData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('会诊大厅'),
        elevation: 0,
      ),
      body: Column(
        children: [
          Container(
            color: Colors.white,
            child: Row(
              key: selectorKey,
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: [
                _buildSection(
                  _selectedDepartmentIndex == null
                      ? '会诊科室'
                      : _departments[_selectedDepartmentIndex].label,
                  onTap: () {
                    if (_departments.isNotEmpty) {
                      _showSelectorDialog(context, RecordType.department);
                    }
                  },
                ),
                _buildSection(
                  _selectedConsultationIndex == null
                      ? '会诊类型'
                      : _consultationTypes[_selectedConsultationIndex].label,
                  onTap: () {
                    if (_consultationTypes.isEmpty) {
                      return;
                    }
                    _showSelectorDialog(context, RecordType.consultation);
                  },
                ),
              ],
            ),
          ),
          Expanded(
            child: SmartRefresher(
              controller: _refreshController,
              enablePullDown: true,
              enablePullUp: _nextPage != 1,
              onRefresh: _fetchData,
              onLoading: _loadMore,
              child: ListView.separated(
                padding: EdgeInsets.symmetric(vertical: 10),
                itemBuilder: (c, i) {
                  return ItemRecordPublish(item: _items[i]);
                },
                itemCount: _items.length,
                separatorBuilder: (BuildContext context, int index) =>
                    CustomDivider(),
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildSection(String title, {GestureTapCallback onTap}) {
    return Expanded(
      child: InkWell(
        onTap: onTap,
        child: Container(
          height: 50,
          alignment: Alignment.center,
          child: Row(
            mainAxisSize: MainAxisSize.min,
            children: [
              Container(
                constraints: BoxConstraints(
                    maxWidth: MediaQuery.of(context).size.width / 3 - 30),
                child: Text(
                  title,
                  overflow: TextOverflow.ellipsis,
                ),
              ),
              Icon(Icons.keyboard_arrow_down, color: Colors.grey[700]),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildMaterialDialogTransitions(
      BuildContext context,
      Animation<double> animation,
      Animation<double> secondaryAnimation,
      Widget child) {
    Animation<Offset> custom;
    custom = Tween<Offset>(
      begin: Offset(0.0, 0.0),
      end: Offset(0.0, 0.0),
    ).animate(animation);
    return SlideTransition(
      position: custom,
      child: child,
    );
  }

  void _showSelectorDialog(BuildContext context, RecordType type) {
    showGeneralDialog(
        context: context,
        barrierLabel: "",
        barrierDismissible: true,
        barrierColor: Colors.transparent,
        transitionDuration: Duration(milliseconds: 0),
        transitionBuilder: _buildMaterialDialogTransitions,
        pageBuilder: (BuildContext context, Animation animation,
            Animation secondaryAnimation) {
          RenderBox renderBox =
              selectorKey.currentContext.findRenderObject() as RenderBox;
          Offset position = renderBox.localToGlobal(Offset.zero);
          return StatefulBuilder(builder: (context1, state) {
            Widget widget;
            switch (type) {
              case RecordType.department:
                widget = _buildDepartmentSelector(state, context);
                break;
              case RecordType.consultation:
                widget = _buildConsultationSelector(state, context);
                break;
            }
            return Padding(
              padding: EdgeInsets.only(
                top: kToolbarHeight + position.dy,
              ),
              child: Material(
                clipBehavior: Clip.antiAlias,
                child: Column(
                  children: [
                    Container(
                      decoration: BoxDecoration(
                          color: Colors.white,
                          border: Border(
                              bottom: BorderSide(color: Colors.grey[300]))),
                      height: 300,
                      child: widget,
                    ),
                    Expanded(
                      child: InkWell(
                        child: Container(),
                        onTap: () {
                          Navigator.pop(context);
                        },
                      ),
                    ),
                  ],
                ),
              ),
            );
          });
        });
  }

  /// 科室选择器
  Widget _buildDepartmentSelector(StateSetter state, BuildContext context) {
    return ListView.separated(
        padding: EdgeInsets.all(0),
        itemBuilder: (c, i) {
          return InkWell(
            child: Container(
              height: 50,
              alignment: Alignment.centerLeft,
              margin: EdgeInsets.symmetric(horizontal: 16),
              child: Text(
                i == 0 ? '不限科室' : _departments[i - 1].label,
                style: TextStyle(
                    color: _selectedDepartmentIndex == i - 1
                        ? Theme.of(context).primaryColor
                        : Colors.black87),
              ),
            ),
            onTap: () {
              Navigator.pop(context);
              setState(() {
                if (i == 0) {
                  _selectedDepartmentIndex = null;
                } else {
                  _selectedDepartmentIndex = i - 1;
                }
              });
              _fetchData();
            },
          );
        },
        separatorBuilder: (c, i) => Divider(),
        itemCount: _departments.length + 1);
  }

  /// 会诊类型选择器
  Widget _buildConsultationSelector(StateSetter state, BuildContext context) {
    return ListView.separated(
        padding: EdgeInsets.all(0),
        itemBuilder: (c, i) {
          return InkWell(
            child: Container(
              height: 50,
              alignment: Alignment.centerLeft,
              margin: EdgeInsets.symmetric(horizontal: 16),
              child: Text(
                i == 0 ? '不限类型' : _consultationTypes[i - 1].label,
                style: TextStyle(
                    color: _selectedConsultationIndex == i - 1
                        ? Theme.of(context).primaryColor
                        : Colors.black87),
              ),
            ),
            onTap: () {
              Navigator.pop(context);
              setState(() {
                if (i == 0) {
                  _selectedConsultationIndex = null;
                } else {
                  _selectedConsultationIndex = i - 1;
                }
              });
              _fetchData();
            },
          );
        },
        separatorBuilder: (c, i) => Divider(),
        itemCount: _consultationTypes.length + 1);
  }

  /// 获取科室列表
  Future<void> _getDepartmentTypes() async {
    var data =
        await XHttp.postJson(sprintf(Urls.DICT_VALUES, ['section_type']));
    if (data != null) {
      ListResponse response = ListResponse.fromJson(data);
      if (response.code == 1) {
        if (mounted) {
          _departments =
              List.from(response.data.map((e) => Department.fromJson(e)));
        }
      }
    }
  }

  /// 获取会诊类型列表
  Future<void> _getConsultationTypes() async {
    var data = await XHttp.postJson(
        sprintf(Urls.DICT_VALUES, ['tab_consultation_ype']));
    if (data != null) {
      ListResponse response = ListResponse.fromJson(data);
      if (response.code == 1) {
        if (mounted) {
          _consultationTypes =
              List.from(response.data.map((e) => Department.fromJson(e)));
        }
      }
    }
  }

  void _fetchData() async {
    var result = await XHttp.postJson(
        sprintf(Urls.RECORD_PUBLISH_LIST, [1, Constants.limit]),
        _buildParams());
    _refreshController.refreshCompleted();
    if (result != null) {
      var response = MapResponse.fromJson(result);
      if (response.code == 1) {
        if (response.data['pages'] == response.data['current']) {
          _nextPage = 1;
        } else {
          _nextPage = response.data['pages'] + 1;
        }
        var records = (response.data['records'] as List)
            .map(
                (e) => ConsultationRecord.fromJson((e as Map<String, dynamic>)))
            .toList();
        if (mounted) {
          setState(() {
            _items = records;
          });
        }
      } else {
        ToastUtil.show(response.msg, context);
      }
    }
  }

  Map<String, dynamic> _buildParams() {
    Map<String, dynamic> params = {};
    // 添加筛选条件
    if (_selectedConsultationIndex != null) {
      params['consultationTypeId'] =
          _consultationTypes[_selectedConsultationIndex].value;
    }
    if (_selectedDepartmentIndex != null) {
      params['hospitalDeptId'] = _departments[_selectedDepartmentIndex].value;
    }
    return params;
  }

  void _loadMore() async {
    var result = await XHttp.postJson(
        sprintf(Urls.RECORD_PUBLISH_LIST, [_nextPage, Constants.limit]),
        _buildParams());
    _refreshController.loadComplete();
    if (result != null) {
      var response = MapResponse.fromJson(result);
      if (response.code == 1) {
        if (response.data['pages'] == response.data['current']) {
          _nextPage = 1;
        } else {
          _nextPage = response.data['pages'] + 1;
        }
        var records = (response.data['records'] as List)
            .map(
                (e) => ConsultationRecord.fromJson((e as Map<String, dynamic>)))
            .toList();
        if (mounted) {
          setState(() {
            _items.addAll(records);
          });
        }
      } else {
        ToastUtil.show(response.msg, context);
      }
    }
  }
}

enum RecordType { department, consultation }
